package com.leador.map.location.log;

import android.location.Location;
import android.net.wifi.ScanResult;

import com.leador.map.location.Const;
import com.leador.map.location.cell.Cdma;
import com.leador.map.location.cell.Gsm;
import com.leador.map.location.util.Utils;
import org.apache.http.protocol.HTTP;
import java.io.UnsupportedEncodingException;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

/**
 *
 */
public class Log {
    private static DecimalFormat df = null;
    private static SimpleDateFormat sdf = null;
    public int cellType = Const.iDefCellType;
    public String imei = Const.strDefImei;
    public String imsi = Const.strDefImsi;
    public String mac = Const.strDefMac;
    public String clientTime = "0000-00-00-00-00-00";
    public String gpsLon = "0";
    public String gpsLat = "0";
    public String gpsSpeed = "0";
    public String gpsAltitude = "0";
    public String gpsAccu = "0";
    public String gpsDirection = "0";
    public String gpsSig = "0";
    public String gpsTime = "0000-00-00-00-00-00";
    public List<Gsm> lstGsm = new ArrayList<Gsm>();
    public List<Cdma> lstCdma = new ArrayList<Cdma>();
    public List<ScanResult> lstScanResult = new ArrayList<ScanResult>();

    public Log() {
        //
    }

    /**
     * 使用指定样式格式化输入字符串
     *
     * @param object
     * @param strPattern
     * @return String
     */
    public static String fmatStr(Object object, String strPattern) {
        if (df == null) {
            df = new DecimalFormat("#");
        }
        df.applyPattern(strPattern);
        String str = df.format(object);
        return str;
    }

    /**
     * 使用指定样式格式化LONG型UTC时间
     *
     * @param l
     * @param strPattern
     * @return String
     */
    public static String formatUTC(long l, String strPattern) {
        if (sdf == null) {
            sdf = new SimpleDateFormat(strPattern);
        } else {
            sdf.applyPattern(strPattern);
        }
        String strResult = null;
        if (l > 0l) {
            strResult = sdf.format(l);
        } else {
            strResult = "0000-00-00-00-00-00";
        }
        return strResult;
    }

    private static byte[] get4BaFromInt(int iValue) {
        byte[] ba = new byte[4];
        ba[0] = (byte) (iValue & 0xFF);
        ba[1] = (byte) (iValue >> 8 & 0xFF);
        ba[2] = (byte) (iValue >> 16 & 0xFF);
        ba[3] = (byte) (iValue >> 24 & 0xFF);
        return ba;
    }

    public static byte[] get1BFromInt(int iValue) {
        byte[] ba = new byte[1];
        ba[0] = (byte) (Math.abs(iValue) & 0xFF);
        return ba;
    }

    private static byte[] get2BaFromStr(String str) {
        return get2BaFromInt(Utils.getInt(str,-1));
    }

    private static byte[] get2BaFromInt(int iValue) {
        byte[] ba = new byte[2];
        ba[0] = (byte) (iValue & 0xFF);
        ba[1] = (byte) (iValue >> 8 & 0xFF);
        return ba;
    }

    public static String ba2Str(byte[] ba) {
        StringBuilder sb = new StringBuilder();
        for (byte b : ba) {
            sb.append(b).append(" ");
        }
        return sb.toString();
    }

    private static byte[] get6BaFromMac(String strMac) {
        byte[] ba = new byte[6];
        String[] sa = strMac.split(":");
        for (int i = 0; i < sa.length; i++) {
            ba[i] = (byte) Integer.parseInt(sa[i], 16);
        }
        return ba;
    }

    /**
     * 设置日志实例中的GPS数据
     *
     * @param 无
     * @return 无
     */
    public void setGps(Location loc, float fGpsSig) {
        gpsLon = getGpsProp(loc, "lon");
        gpsLat = getGpsProp(loc, "lat");
        gpsSpeed = getGpsProp(loc, "speed");
        gpsAltitude = getGpsProp(loc, "altitude");
        gpsAccu = getGpsProp(loc, "accuracy");
        gpsDirection = getGpsProp(loc, "bearing");
        df.applyPattern("0");
        gpsSig = df.format(fGpsSig);
        long l = Long.parseLong(getGpsProp(loc, "time"));
        gpsTime = formatUTC(l, "yyyy-MM-dd-HH-mm-ss");
    }

    /**
     * 设置日志实例中的GSM数据
     *
     * @param List
     * @return 无
     */
    public void setGsm(List<Gsm> lstGsm) {
        this.lstGsm.addAll(lstGsm);
    }

    /**
     * 设置日志实例中的CDMA数据
     *
     * @param List
     * @return 无
     */
    public void setCdma(List<Cdma> lstCdma) {
        this.lstCdma.addAll(lstCdma);
    }

    /**
     * 设置日志实例中的WIFI数据
     *
     * @param List
     * @return 无
     */
    public void setWifi(List<ScanResult> lstScanResult) {
        this.lstScanResult.addAll(lstScanResult);
    }

    /**
     * 获取日志实例中的手机网络类型字符串
     *
     * @param 无
     * @return String
     */
    public String getCellTypeBaStr() {
        if (lstGsm.size() > 0) {
            cellType = 0;
        } else if (lstCdma.size() > 0) {
            cellType = 1;
        } else {
            cellType = Const.iDefCellType;
        }
        return ba2Str(get1BFromInt(cellType));
    }

    /**
     * 获取日志实例中的IMEI&IMSI&MAC字符串
     *
     * @param 无
     * @return String
     */
    public String getImeiImsiMacBaStr() {
        if (imei == null) {
            imei = Const.strDefImei;
        }
        if (imsi == null) {
            imsi = Const.strDefImsi;
        }
        if (mac == null) {
            mac = Const.strDefMac;
        }
        StringBuilder sb = new StringBuilder();
        sb.append(ba2Str(get1BFromInt(imei.length())));
        try {
            sb.append(ba2Str(imei.getBytes(HTTP.UTF_8)));
        } catch (UnsupportedEncodingException e) {
            sb.append(ba2Str(Const.strDefImei.getBytes()));
        }
        sb.append(ba2Str(get1BFromInt(imsi.length())));
        try {
            sb.append(ba2Str(imsi.getBytes(HTTP.UTF_8)));
        } catch (UnsupportedEncodingException e) {
            sb.append(ba2Str(Const.strDefImsi.getBytes()));
        }
        sb.append(ba2Str(get1BFromInt(mac.length())));
        try {
            sb.append(ba2Str(mac.getBytes(HTTP.UTF_8)));
        } catch (UnsupportedEncodingException e) {
            sb.append(ba2Str(Const.strDefMac.getBytes()));
        }
        return sb.toString();
    }

    /**
     * 获取日志实例中的时间字符串
     *
     * @param 无
     * @return String
     */
    public String getTimeBaStr() {
        clientTime = formatUTC(Utils.getTime(), "yyyy-MM-dd-HH-mm-ss");
        String[] sa = clientTime.split("-");
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < sa.length; i++) {
            int iValue = Integer.parseInt(sa[i]);
            if (i == 0) {
                sb.append(ba2Str(get2BaFromInt(iValue)));
            } else {
                sb.append(ba2Str(get1BFromInt(iValue)));
            }
        }
        sb.trimToSize();
        return sb.toString();
    }

    /**
     * 获取日志实例中的GPS字符串
     *
     * @param 无
     * @return String
     */
    public String getGpsBaStr() {
        int iLatE6 = (int) (Double.valueOf(gpsLat) * 1E6);
        int iLonE6 = (int) (Double.valueOf(gpsLon) * 1E6);
        StringBuilder sb = new StringBuilder();
        sb.append(ba2Str(get4BaFromInt(iLatE6)));
        sb.append(ba2Str(get4BaFromInt(iLonE6)));
        sb.append(ba2Str(get2BaFromStr(gpsSpeed)));
        sb.append(ba2Str(get2BaFromStr(gpsDirection)));
        sb.append(ba2Str(get2BaFromStr(gpsAltitude)));
        sb.append(ba2Str(get2BaFromStr(gpsAccu)));
        sb.append(ba2Str(get2BaFromStr(gpsSig)));
        String[] sa = gpsTime.split("-");
        for (int i = 0; i < sa.length; i++) {
            int iValue = Integer.parseInt(sa[i]);
            if (i == 0) {
                sb.append(ba2Str(get2BaFromInt(iValue)));
            } else {
                sb.append(ba2Str(get1BFromInt(iValue)));
            }
        }
        sb.trimToSize();
        return sb.toString();
    }

    /**
     * 获取日志实例中的单个GSM字符串
     *
     * @param Gsm
     * @param int [0:主基站/1:周边基站]
     * @return String
     */
    private String getOneGsmBaStr(Gsm gsm, int iType) {
        String strMcc = "";
        String strMnc = "";
        if (iType == 0) {
            strMcc = ba2Str(get2BaFromStr(gsm.getMcc()));
            strMnc = ba2Str(get2BaFromStr(gsm.getMnc()));
        }
        StringBuilder sb = new StringBuilder();
        sb.append(strMcc);
        sb.append(strMnc);
        sb.append(ba2Str(get4BaFromInt(gsm.getLac())));
        sb.append(ba2Str(get4BaFromInt(gsm.getCid())));
        sb.append(ba2Str(get1BFromInt(gsm.getSig())));
        return sb.toString();
    }

    /**
     * 获取日志实例中的GSM字符串
     *
     * @param 无
     * @return String
     */
    public String getGsmBaStr() {
        String strResult = "";
        if (cellType == 0) {
            int iGsmNum = lstGsm.size();
            StringBuilder sb = new StringBuilder();
            sb.append(getOneGsmBaStr(lstGsm.get(0), 0));
            sb.append(ba2Str(get1BFromInt(iGsmNum - 1)));
            if (iGsmNum > 1) {
                for (int i = 1; i < iGsmNum; i++) {
                    sb.append(getOneGsmBaStr(lstGsm.get(i), 1));
                }
            }
            strResult = sb.toString();
            sb.delete(0, sb.length());
            sb = null;
        }
        return strResult;
    }

    /**
     * 获取日志实例中的CDMA字符串
     *
     * @param 无
     * @return String
     */
    public String getCdmaBaStr() {
        StringBuilder sb = new StringBuilder();
        if (cellType == 1) {
            Cdma cdma = lstCdma.get(0);
            int iMcc = Integer.parseInt(cdma.getMcc());
            sb.append(ba2Str(get2BaFromInt(iMcc)));
            sb.append(ba2Str(get2BaFromInt(cdma.getSid())));
            sb.append(ba2Str(get4BaFromInt(cdma.getNid())));
            sb.append(ba2Str(get4BaFromInt(cdma.getBid())));
            sb.append(ba2Str(get1BFromInt(cdma.getSig())));
        }
        return sb.toString();
    }

    /**
     * 获取日志实例中的WIFI字符串
     *
     * @param 无
     * @return String
     */
    public String getWifiBaStr() {
        int iWifiNum = lstScanResult.size();
        if (iWifiNum > Const.iMaxWifiInOneLog) {
            iWifiNum = Const.iMaxWifiInOneLog;
        }
        StringBuilder sb = new StringBuilder();
        sb.append(ba2Str(get1BFromInt(iWifiNum)));
        for (int i = 0; i < iWifiNum; i++) {
            ScanResult scanResult = lstScanResult.get(i);
            sb.append(ba2Str(get6BaFromMac(scanResult.BSSID)));
            sb.append(ba2Str(get1BFromInt(scanResult.level)));
            sb.append(ba2Str(get1BFromInt(scanResult.SSID.length())));
            try {
                sb.append(ba2Str(scanResult.SSID.getBytes(HTTP.UTF_8)));
            } catch (UnsupportedEncodingException e) {
                sb.append(ba2Str("null".getBytes()));
            }
        }
        sb.trimToSize();
        return sb.toString();
    }

    /**
     * 从LOCATION实例中获取GPS属性值
     *
     * @param Location
     * @param String
     * @return String
     */
    private String getGpsProp(Location loc, String strName) {
        String strValue = "";
        if (strName.equals("lon")) {
            strValue = fmatStr(loc.getLongitude(), "#.000000");
        } else if (strName.equals("lat")) {
            strValue = fmatStr(loc.getLatitude(), "#.000000");
        } else if (strName.equals("speed")) {
            strValue = fmatStr(loc.getSpeed(), "#");
        } else if (strName.equals("altitude")) {
            strValue = fmatStr(loc.getAltitude(), "#");
        } else if (strName.equals("accuracy")) {
            strValue = fmatStr(loc.getAccuracy(), "#");
        } else if (strName.equals("bearing")) {
            strValue = fmatStr(loc.getBearing(), "#");
        } else if (strName.equals("time")) {
            strValue = fmatStr(loc.getTime(), "#");
        } else {
            Utils.writeCat("illegal gps property name");
        }
        return strValue;
    }

    /**
     * 销毁日志实例
     *
     * @param 无
     * @return 无
     */
    public void destroy() {
        lstGsm.clear();
        lstGsm = null;
        lstCdma.clear();
        lstCdma = null;
        lstScanResult.clear();
        lstScanResult = null;
        df = null;
    }
}